package controleur;

import ecom.beans.*;
import ecom.beans.EuroConvertorBean.Currency;
import ecom.beans.exception.*;
import java.io.IOException;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.ejb.EJB;
import javax.naming.*;
import javax.servlet.http.*;
import javax.servlet.*;


/**
 *
 * @author DE SILVA
 */
public class Controleur extends HttpServlet implements Serializable {

    @EJB
    private EcomCustomerRemote customerBean;
    private Context initialContext;
    private InitialContext ic;
    HttpSession session;
    DecimalFormat myFormatter;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        if (request.getParameter("action").equals("initialize")) { ///INITIALIZE
            session = request.getSession();
            session.setMaxInactiveInterval(1000);
            Set<ProductcategoryBean> categories = customerBean.getAllCategories(" ORDER BY p.name");
            Set<ProductstoreBean> productstores = customerBean.getAllStores(null);
            Set<PurchaseBean> cart = customerBean.getPurchasesInCart();
            Set<PurchaseBean> lastSales = customerBean.getLastSales(null);
            Set<StockBean> bestStocks = customerBean.getBestStocks(" ORDER BY s.price", null);
            List<String> currencies = customerBean.getCurrencySymbols();
            Currency currentCurrency = Currency.getDefault();
            session.setAttribute("currentCurrency", currentCurrency);
            session.setAttribute("currencies", currencies);
            session.setAttribute("bestStocks", bestStocks);
            session.setAttribute("lastSales", lastSales);
            session.setAttribute("categories", categories);
            session.setAttribute("cart", cart);
            session.setAttribute("productstores", productstores);
            request.getRequestDispatcher("accueil.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("login")) {  ///LOGIN
            String pseudo = request.getParameter("pseudo");
            String password = request.getParameter("password");
            String errorAuth = null;
            try {
                customerBean.setUser(customerBean.getUserByPseudoAndPassword(pseudo, password));
                session.setAttribute("user", customerBean.getUser());
            } catch (DAONotFoundException ex) {
                errorAuth = "L'utilisateur ou le mot de passe est incorrect";
                request.setAttribute("errorAuth", errorAuth);
                request.getRequestDispatcher("login.jsp").forward(request, response);
            }
            request.getRequestDispatcher("accueil.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("deposit")) {    ///DEPOSIT
            try {
                Double montant = Double.valueOf(request.getParameter("montant"));
                customerBean.deposit(montant);
            } catch (NotLoginException ex) {
                request.setAttribute("error", "Veuillez vous connecter pour déposer de l'argent");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (NotAccountAssociatedToUser ex) {
                request.setAttribute("error", "Vous n'avez pas de compte bancaire");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (NumberFormatException e) {
                request.setAttribute("error", "Veuillez entrer un nombre");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            }
            request.getRequestDispatcher("accueil.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("remove_product")) { ///REMOVE PRODUCT
            Long idProduct = Long.valueOf(request.getParameter("idProduct"));
            Long idProductstore = Long.valueOf(request.getParameter("idProductstore"));
            try {
                customerBean.removeProductFromCart(idProduct, idProductstore);
                Set<PurchaseBean> cart = customerBean.getPurchasesInCart();
                Currency currentCurrency = (Currency) session.getAttribute("currentCurrency");
                Double totalPrice = customerBean.getCartTotalPriceInCurrentDevise(currentCurrency.name());
                request.setAttribute("totalPrice", myFormatter.format(totalPrice));
                session.setAttribute("cart", cart);
            } catch (CartException ex) {
                request.setAttribute("error", "Le produit n'a pas été trouvé dans le caddie");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (DeviseException ex) {
                String error = "La devise courante n'a pas été trouvée";
                request.setAttribute("error", error);
                request.getRequestDispatcher("error.jsp").forward(request, response);
            }
            request.getRequestDispatcher("shopping_cart.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("update_quantity_cart")) {   ///UPDATE QUANTITY CART
            Long idProduct = Long.valueOf(request.getParameter("idProduct"));
            Long idProductstore = Long.valueOf(request.getParameter("idProductstore"));
            Integer quantity = Integer.valueOf(request.getParameter("quantity"));
            try {
                customerBean.updateQuantityProduct(idProduct, idProductstore, quantity);
                Set<PurchaseBean> cart = customerBean.getPurchasesInCart();
                Currency currentCurrency = (Currency) session.getAttribute("currentCurrency");
                Double totalPrice = customerBean.getCartTotalPriceInCurrentDevise(currentCurrency.name());
                request.setAttribute("totalPrice", myFormatter.format(totalPrice));
                session.setAttribute("cart", cart);
            } catch (StockQuantityUnavailable ex) {
                request.setAttribute("error", "La quantité demandée n'est pas disponible dans le stock du magasin");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (CartException ex) {
                request.setAttribute("error", "Le produit n'a pas été trouvé dans le caddie");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (DeviseException ex) {
                String error = "La devise courante n'a pas été trouvée";
                request.setAttribute("error", error);
                request.getRequestDispatcher("error.jsp").forward(request, response);
            }
            request.getRequestDispatcher("shopping_cart.jsp").forward(request, response);


        } else if (request.getParameter("action").equals("logout")) {   ///LOG OUT
            customerBean.setUser(null);
            session.removeAttribute("user");
            session.removeAttribute("cart");
            request.getRequestDispatcher("accueil.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("createaccount")) { ///CREATE ACCOUNT
            String pseudo = request.getParameter("pseudo");
            String password = request.getParameter("password");
            String email_address = request.getParameter("email_address");
            String address = request.getParameter("address");
            String postcode = request.getParameter("postcode");
            String city = request.getParameter("city");
            String country = request.getParameter("country");
            String currency = request.getParameter("currency");
            String telephone = request.getParameter("telephone");
            String iban = request.getParameter("iban");
            List<String> list = new ArrayList<String>();
            list.add("pseudo");
            list.add(pseudo);
            list.add("email_address");
            list.add(email_address);
            list.add("address");
            list.add(address);
            list.add("postcode");
            list.add(postcode);
            list.add("city");
            list.add(city);
            list.add("telephone");
            list.add(telephone);
            list.add("iban");
            list.add(iban);
            try {
                customerBean.createUser(pseudo, password, email_address, address, postcode, city, country, currency, telephone, false, iban, new Double(0));
                customerBean.setUser(customerBean.getUserByPseudoAndPassword(pseudo, password));
                session.setAttribute("user", customerBean.getUser());
            } catch (UserBeanException ex) {
               } catch (DAONotUniqueException ex) {
                 } catch (AccountBeanException ex) {
                  } catch (DAONotFoundException ex) {
                String error = "L'utilisateur ou le mot de passe est incorrect";
                request.setAttribute("error", error);
                request.getRequestDispatcher("acceuil.jsp").forward(request, response);
            }
            request.getRequestDispatcher("accueil.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("modifiercompte")) { ///MODIFIER ACCOUNT
            String pseudo = request.getParameter("pseudo");
            String password = request.getParameter("password");
            String email_address = request.getParameter("email_address");
            String address = request.getParameter("address");
            String postcode = request.getParameter("postcode");
            String city = request.getParameter("city");
            String country = request.getParameter("country");
            String currency = request.getParameter("currency");
            String telephone = request.getParameter("telephone");
            String iban = request.getParameter("iban");
            List<String> list = new ArrayList<String>();
            list.add("pseudo");
            list.add(pseudo);
            list.add("email_address");
            list.add(email_address);
            list.add("address");
            list.add(address);
            list.add("postcode");
            list.add(postcode);
            list.add("city");
            list.add(city);
            list.add("telephone");
            list.add(telephone);
            list.add("iban");
            list.add(iban);
            customerBean.updateUser(pseudo, password, iban, address, postcode, city, country, currency, telephone);
            request.getRequestDispatcher("accueil.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("modifaccount")) { ///MODIF ACCOUNT
            UserBean u = customerBean.getUser();
            String pseudo = u.getPseudo();
            String password = u.getPassword();
            String email_address = u.getEmail();
            String address = u.getAdress();
            String postcode = u.getPostalCode();
            String city = u.getCity();
            String country = u.getCountry();
            String currency = u.getCurrency();
            String telephone = u.getPseudo();
            String iban = u.getAccount().getIban();
            List<String> list = new ArrayList<String>();
            list.add("pseudo");
            list.add(pseudo);
            list.add("email_address");
            list.add(email_address);
            list.add("address");
            list.add(address);
            list.add("postcode");
            list.add(postcode);
            list.add("city");
            list.add(city);
            list.add("telephone");
            list.add(telephone);
            list.add("iban");
            list.add(iban);
            request.getRequestDispatcher("modifaccount.jsp").forward(request, response);

        } else if (request.getParameter("action").contains(".jsp")) {   ///REDIRECT
            String page = request.getParameter("action");
            request.getRequestDispatcher(page).forward(request, response);

        } else if (request.getParameter("action").contains("add_product")) {     ///ADD PRODUCT
            Long idProduct = Long.valueOf(request.getParameter("idProduct"));
            Long idProductstore = Long.valueOf(request.getParameter("idProductstore"));
            try {
                customerBean.addProductToCart(idProduct, idProductstore, new Integer(1));
                Set<PurchaseBean> cart = customerBean.getPurchasesInCart();
                Currency currentCurrency = (Currency) session.getAttribute("currentCurrency");
                Double totalPrice = customerBean.getCartTotalPriceInCurrentDevise(currentCurrency.name());
                request.setAttribute("totalPrice", myFormatter.format(totalPrice));
                session.setAttribute("cart", cart);
            } catch (DeviseException ex) {
                String error = "La devise courante n'a pas été trouvée";
                request.setAttribute("error", error);
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (StockQuantityUnavailable ex) {
                String error = "La quantité demandée n'est pas valable en stock";
                request.setAttribute("error", error);
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (CartException ex) {
                String error = "L'achat du caddie a déjà été effectué";
                request.setAttribute("error", error);
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (NotAccountAssociatedToUser ex) {
                String error = "Aucun compte n'est associé à votre utilisateur";
                request.setAttribute("error", error);
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (NotLoginException ex) {
                String error = "Vous devez vous connecter pour ajouter un produit au caddie";
                request.setAttribute("error", error);
                request.getRequestDispatcher("error.jsp").forward(request, response);
            }
            request.getRequestDispatcher("shopping_cart.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("search")) { ///SEARCH
            String keywords = request.getParameter("keywords");
            Set<StockBean> stock = customerBean.getStockByProductNameOrDescription(keywords, null, " ORDER BY s.price");
            request.setAttribute("stock", stock);
            request.getRequestDispatcher("search.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("list_productscategory")) { ///LIST PRODUCTS WITH CATEG
            session.removeAttribute("idProductstore");
            Long idProductcategory = Long.valueOf(request.getParameter("idProductcategory"));
            Set<StockBean> stock;
            if (idProductcategory.equals(new Long(0))) {
                stock = customerBean.getStocks(" ORDER BY s.price");
            } else {
                stock = customerBean.getStockByIdProductcategory(idProductcategory, " ORDER BY s.price");
            }
            request.setAttribute("stock", stock);
            try {
                request.setAttribute("title", customerBean.getProductcategoryById(idProductcategory).getName());
            } catch (DAONotFoundException ex) {
                request.setAttribute("title", "Toutes les catégories");
            }
            session.setAttribute("idProductcategory", idProductcategory);
            request.getRequestDispatcher("list_productscategory.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("list_productsstore")) { ///LIST PRODUCTS WITH STORE
            session.removeAttribute("idProductcategory");
            Long idProductstore = Long.valueOf(request.getParameter("idProductstore"));
            Set<StockBean> stock;
            if (idProductstore.equals(new Long(0))) {
                stock = customerBean.getStocks(" ORDER BY s.price");
            } else {
                stock = customerBean.getStockByIdProductstore(idProductstore, " ORDER BY s.price");
            }
            request.setAttribute("stock", stock);
            try {
                request.setAttribute("title", customerBean.getProductstoreById(idProductstore).getName());
            } catch (DAONotFoundException ex) {
                request.setAttribute("title", "Tous les magasins");
            }
            session.setAttribute("idProductstore", idProductstore);
            request.getRequestDispatcher("list_productsstore.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("filtrerByCateg")) { ///FILTRER PRODUCT BY CATEG
            Long idProductstore = (Long) session.getAttribute("idProductstore");
            Long idProductcategory = Long.valueOf(request.getParameter("idProductcategory"));
            Set<StockBean> stock;
            if (idProductcategory.equals(new Long(0)) && idProductstore.equals(new Long(0))) {
                stock = customerBean.getStocks(" ORDER BY s.price");
            } else if (idProductcategory.equals(new Long(0))) {
                stock = customerBean.getStockByIdProductstore(idProductstore, " ORDER BY s.price");
            } else if (idProductstore.equals(new Long(0))) {
                stock = customerBean.getStockByIdProductcategory(idProductcategory, " ORDER BY s.price");
            } else {
                stock = customerBean.getStockByIdProductcategoryAndIdProductstore(idProductcategory, idProductstore, " ORDER BY s.price");
            }
            try {
                request.setAttribute("title", customerBean.getProductstoreById(idProductstore).getName());
            } catch (DAONotFoundException ex) {
                request.setAttribute("title", "Tous les magasins");
            }
            session.setAttribute("idProductcategory", idProductcategory);
            request.setAttribute("stock", stock);
            request.getRequestDispatcher("list_productsstore.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("filtrerByStore")) {   ///FILTRER PRODUCT WITH STORE
            Long idProductcategory = (Long) session.getAttribute("idProductcategory");
            Long idProductstore = Long.valueOf(request.getParameter("idProductstore"));
            Set<StockBean> stock;
            if (idProductcategory.equals(new Long(0)) && idProductstore.equals(new Long(0))) {
                stock = customerBean.getStocks(" ORDER BY s.price");
            } else if (idProductcategory.equals(new Long(0))) {
                stock = customerBean.getStockByIdProductstore(idProductstore, " ORDER BY s.price");
            } else if (idProductstore.equals(new Long(0))) {
                stock = customerBean.getStockByIdProductcategory(idProductcategory, " ORDER BY s.price");
            } else {
                stock = customerBean.getStockByIdProductcategoryAndIdProductstore(idProductcategory, idProductstore, " ORDER BY s.price");
            }
            try {
                request.setAttribute("title", customerBean.getProductcategoryById(idProductcategory).getName());
            } catch (DAONotFoundException ex) {
                request.setAttribute("title", "Toutes les catégories");
            }
            session.setAttribute("idProductstore", idProductstore);
            request.setAttribute("stock", stock);
            request.getRequestDispatcher("list_productscategory.jsp").forward(request, response);

        } else if (request.getParameter("action").equals("products_info")) { ///PRODUCTS INFO
            Long idProduct = Long.valueOf(request.getParameter("idProduct"));
            Long idProductstore = Long.valueOf(request.getParameter("idProductstore"));
            try {
                StockBean stock = customerBean.getStockByIdProductstoreAndIdProduct(idProductstore, idProduct);
                request.setAttribute("stock", stock);
                request.getRequestDispatcher("products_info.jsp").forward(request, response);
            } catch (DAONotFoundException ex) {
                request.setAttribute("error", "Le produit n'a pas été touvé");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            }
        } else if (request.getParameter("action").equals("change_currency")) { ///CHANGE CURRENCY
            String currency = request.getParameter("currency");
            try {
                Currency currentCurrency = Currency.get(currency);
                session.setAttribute("currentCurrency", currentCurrency);
            } catch (DeviseException ex) {
                request.setAttribute("error", "La monnaie(" + currency + ") n'a pas été trouvée");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            }
            request.getRequestDispatcher("accueil.jsp").forward(request, response);
        } else if (request.getParameter("action").equals("getshopping_cart")) { ///GET SHOPPING CART
            try {
                Set<PurchaseBean> cart = customerBean.getPurchasesInCart();
                Currency currentCurrency = (Currency) session.getAttribute("currentCurrency");
                Double totalPrice = customerBean.getCartTotalPriceInCurrentDevise(currentCurrency.name());
                request.setAttribute("totalPrice", myFormatter.format(totalPrice));
                session.setAttribute("cart", cart);
            } catch (DeviseException ex) {
                request.setAttribute("error", "La monnaie n'a pas été trouvée");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            }
            request.getRequestDispatcher("shopping_cart.jsp").forward(request, response);
        } else if (request.getParameter("action").equals("buy_cart")) {   /// BUY CART
            try {
                customerBean.buyCart();
                Set<PurchaseBean> cart = customerBean.getPurchasesInCart();
                session.setAttribute("cart", cart);
            } catch (NotLoginException ex) {
                request.setAttribute("error", "Vous devez vous connecter pour acheter votre caddie");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (NotAccountAssociatedToUser ex) {
                request.setAttribute("error", "Aucun compte bancaire n'est associé à votre compte utilisateur");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (CartException ex) {
                request.setAttribute("error", "Votre caddie a déjà été acheté");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            } catch (AccountBeanException ex) {
                request.setAttribute("error", "Votre solde de compte est insuffisant");
                request.getRequestDispatcher("error.jsp").forward(request, response);
            }
            request.getRequestDispatcher("confirmation_achat.jsp").forward(request, response);
        } 
                 

    }

 
    
     // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";

    }// </editor-fold>
}
